Skip to content

fix(memory): Fix memory leak for RecorderClass::m_crcInfo#2713

Open
Caball009 wants to merge 8 commits into
TheSuperHackers:mainfrom
Caball009:fix_memory_leak_crcInfo
Open

fix(memory): Fix memory leak for RecorderClass::m_crcInfo#2713
Caball009 wants to merge 8 commits into
TheSuperHackers:mainfrom
Caball009:fix_memory_leak_crcInfo

Conversation

@Caball009
Copy link
Copy Markdown

@Caball009 Caball009 commented May 14, 2026

This PR fixes a memory leak for RecorderClass::m_crcInfo. I decided to fix this one by not allocating the CRCInfo object dynamically. This did require a larger change of moving the class to the header, though.

See commits for clean diffs.

TODO:

  • Replicate in Generals.

@Caball009 Caball009 added Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour Memory Is memory related Fix Is fixing something, but is not user facing labels May 14, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR fixes a memory leak where RecorderClass::m_crcInfo was heap-allocated via NEW CRCInfo(...) in playbackFile() but never deleted. The fix converts m_crcInfo from a raw pointer to a value member, which required moving the CRCInfo class definition from a file-local .cpp class into a nested protected class inside RecorderClass in the header.

  • CRCInfo is moved to the header as a nested class with a new default constructor, and m_crcInfo becomes a direct value member of RecorderClass.
  • All pointer dereferences (->) across both Recorder.cpp files are replaced with direct member access (.), and the NEW CRCInfo(...) in playbackFile() is replaced with copy-assignment of a stack-constructed temporary.
  • The fix is applied identically to both the Generals/ and GeneralsMD/ trees.

Confidence Score: 5/5

Safe to merge — the change is a straightforward conversion from a raw owning pointer to a value member with no logic changes.

The conversion from CRCInfo* to CRCInfo is mechanically correct: a default constructor was added (properly zero-initialising all fields), playbackFile() reinitialises the member via copy-assignment (which also clears any stale m_data), and all call sites were updated consistently across both game trees. No new allocation paths or ownership ambiguities are introduced.

No files require special attention.

Important Files Changed

Filename Overview
Generals/Code/GameEngine/Include/Common/Recorder.h CRCInfo moved from .cpp file-local class to nested protected class; m_crcInfo changed from pointer to value member; default constructor added.
Generals/Code/GameEngine/Source/Common/Recorder.cpp Old file-local CRCInfo class removed; CRCInfo method bodies moved to scoped RecorderClass::CRCInfo::; all m_crcInfo-> uses replaced with m_crcInfo.*; playbackFile() uses value assignment instead of NEW.
GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Identical structural change to the Generals header — CRCInfo nested in RecorderClass, m_crcInfo as value member.
GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp Mirror of the Generals .cpp change — old file-local CRCInfo removed, method bodies re-scoped, pointer access replaced with value access.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class RecorderClass {
        #CRCInfo m_crcInfo
        +RecorderClass()
        +~RecorderClass()
        +playbackFile(filename) Bool
        +handleCRCMessage(newCRC, playerIndex, fromPlayback)
        +sawCRCMismatch() Bool
    }

    class CRCInfo {
        #Bool m_sawCRCMismatch
        #Bool m_skippedOne
        #UnsignedInt m_localPlayer
        #list~UnsignedInt~ m_data
        +CRCInfo()
        +CRCInfo(localPlayer, isMultiplayer)
        +addCRC(val)
        +readCRC() UnsignedInt
        +GetQueueSize() int
        +getLocalPlayer() UnsignedInt
        +setSawCRCMismatch()
        +sawCRCMismatch() Bool
    }

    RecorderClass *-- CRCInfo : nested class (value member)

    note for RecorderClass "BEFORE: CRCInfo* m_crcInfo (heap via NEW, never deleted)\nAFTER: CRCInfo m_crcInfo (value member, auto-managed)"
Loading

Reviews (6): Last reviewed commit: "Tweaked 'CRCInfo' TSH comment." | Re-trigger Greptile

@Caball009 Caball009 force-pushed the fix_memory_leak_crcInfo branch from 282478b to c5e3079 Compare May 14, 2026 19:54
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Copy link
Copy Markdown

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. Needs replicate to Generals.

Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
@Caball009 Caball009 force-pushed the fix_memory_leak_crcInfo branch from e99381e to 82efc2a Compare May 19, 2026 22:14
@Caball009
Copy link
Copy Markdown
Author

Rebased to include the fix for the CI Replay checker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Fix Is fixing something, but is not user facing Gen Relates to Generals Memory Is memory related Minor Severity: Minor < Major < Critical < Blocker ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants